﻿using System;
using System.Text;
using System.Web.Mvc;
using System.Web.Routing;
using ChoViet.Lib.Helpers;
using ChoViet.Lib.Common;

namespace ChoViet.Lib.Paging
{
	public class Pager
	{
		private ViewContext viewContext;
		private readonly int pageSize;
		private readonly int currentPage;
		private readonly int totalItemCount;
		private readonly RouteValueDictionary linkWithoutPageValuesDictionary;

		public Pager(ViewContext viewContext, int pageSize, int currentPage, int totalItemCount, RouteValueDictionary valuesDictionary)
		{
			this.viewContext = viewContext;
			this.pageSize = pageSize;
			this.currentPage = currentPage;
			this.totalItemCount = totalItemCount;
			this.linkWithoutPageValuesDictionary = valuesDictionary;
		}

		public string RenderHtml()
		{
			int pageCount = (int)Math.Ceiling(this.totalItemCount / (double)this.pageSize);
			int nrOfPagesToDisplay = 10;

			var sb = new StringBuilder();

			// Previous
			if (this.currentPage > 1)
			{
				sb.Append(GeneratePageLink("&lt;", this.currentPage - 1));
			}
			else
			{
				sb.Append("<span class=\"disabled\">&lt;</span>");
			}

			int start = 1;
			int end = pageCount;

			if (pageCount > nrOfPagesToDisplay)
			{
				int middle = (int)Math.Ceiling(nrOfPagesToDisplay / 2d) - 1;
				int below = (this.currentPage - middle);
				int above = (this.currentPage + middle);

				if (below < 4)
				{
					above = nrOfPagesToDisplay;
					below = 1;
				}
				else if (above > (pageCount - 4))
				{
					above = pageCount;
					below = (pageCount - nrOfPagesToDisplay);
				}

				start = below;
				end = above;
			}

			if (start > 3)
			{
				sb.Append(GeneratePageLink("1", 1));
				sb.Append(GeneratePageLink("2", 2));
				sb.Append("...");
			}
			for (int i = start; i <= end; i++)
			{
				if (i == this.currentPage)
				{
					sb.AppendFormat("<span class=\"current\">{0}</span>", i);
				}
				else
				{
					sb.Append(GeneratePageLink(i.ToString(), i));
				}
			}
			if (end < (pageCount - 3))
			{
				sb.Append("...");
				sb.Append(GeneratePageLink((pageCount - 1).ToString(), pageCount - 1));
				sb.Append(GeneratePageLink(pageCount.ToString(), pageCount));
			}

			// Next
			if (this.currentPage < pageCount)
			{
				sb.Append(GeneratePageLink("&gt;", (this.currentPage + 1)));
			}
			else
			{
				sb.Append("<span class=\"disabled\">&gt;</span>");
			}
			return sb.ToString();
		}
        public string RenderHtml(bool rewriteYN)
        {
            if (rewriteYN == false) return RenderHtml();
            int pageCount = (int)Math.Ceiling(this.totalItemCount / (double)this.pageSize);
            int nrOfPagesToDisplay = 10;

            var sb = new StringBuilder();

            // Previous
            if (this.currentPage > 1)
            {
                sb.Append(GeneratePageRewriteLink("&lt;", this.currentPage - 1));
            }
            else
            {
                sb.Append("<span class=\"disabled\">&lt;</span>");
            }

            int start = 1;
            int end = pageCount;

            if (pageCount > nrOfPagesToDisplay)
            {
                int middle = (int)Math.Ceiling(nrOfPagesToDisplay / 2d) - 1;
                int below = (this.currentPage - middle);
                int above = (this.currentPage + middle);

                if (below < 4)
                {
                    above = nrOfPagesToDisplay;
                    below = 1;
                }
                else if (above > (pageCount - 4))
                {
                    above = pageCount;
                    below = (pageCount - nrOfPagesToDisplay);
                }

                start = below;
                end = above;
            }

            if (start > 3)
            {
                sb.Append(GeneratePageRewriteLink("1", 1));
                sb.Append(GeneratePageRewriteLink("2", 2));
                sb.Append("...");
            }
            for (int i = start; i <= end; i++)
            {
                if (i == this.currentPage)
                {
                    sb.AppendFormat("<span class=\"current\">{0}</span>", i);
                }
                else
                {
                    sb.Append(GeneratePageRewriteLink(i.ToString(), i));
                }
            }
            if (end < (pageCount - 3))
            {
                sb.Append("...");
                sb.Append(GeneratePageRewriteLink((pageCount - 1).ToString(), pageCount - 1));
                sb.Append(GeneratePageRewriteLink(pageCount.ToString(), pageCount));
            }

            // Next
            if (this.currentPage < pageCount)
            {
                sb.Append(GeneratePageRewriteLink("&gt;", (this.currentPage + 1)));
            }
            else
            {
                sb.Append("<span class=\"disabled\">&gt;</span>");
            }
            return sb.ToString();
        }
        private string GeneratePageRewriteLink(string linkText, int pageNumber)
        {
            var pageLinkValueDictionary = new RouteValueDictionary(this.linkWithoutPageValuesDictionary);
            pageLinkValueDictionary.Add("page", pageNumber);
            var virtualPathData = RouteTable.Routes.GetVirtualPathForArea(this.viewContext.RequestContext, pageLinkValueDictionary);
            var clientName = this.viewContext.RequestContext.RouteData.Values["clientName"] != null ?
                this.viewContext.RequestContext.RouteData.Values["clientName"].ToString() : string.Empty;
            if (virtualPathData != null)
            {
                string linkFormat = "<a href=\"{0}\">{1}</a>";
                //return String.Format(linkFormat, virtualPathData.VirtualPath, linkText);
                var link = string.Empty;
                var hasId = false;
                var controller = this.viewContext.RequestContext.RouteData.Values["controller"].ToString();
                var action = this.viewContext.RequestContext.RouteData.Values["action"].ToString();
                var id = this.viewContext.RequestContext.RouteData.Values["id"];
                StringBuilder actionLink = new StringBuilder();
                var rewriteUrl = string.Empty;
                /*
                rewriteUrl = "/" + TextHelper.ToUrlFriendly(clientName) + "_{0}" + controller.Substring(0, 1);
                switch (action.ToLower())
                {
                    case "index":
                        switch (controller)
                        {
                            case "product":
                                rewriteUrl = "/" + TextHelper.ToUrlFriendly(clientName) + "/p";
                                break;
                            case "demand":
                                rewriteUrl = "/" + TextHelper.ToUrlFriendly(clientName) + "/dm";
                                break;
                            case "shop":
                                rewriteUrl = "/" + TextHelper.ToUrlFriendly(clientName) + "/s";
                                break;
                            default:
                                rewriteUrl = string.Format(rewriteUrl, string.Empty);
                                break;
                        }
                        break;
                    case "list":
                    case "category":

                        switch (controller)
                        {
                            case "product":
                                rewriteUrl = "/" + TextHelper.ToUrlFriendly(clientName) + "/" + TextHelper.ToUrlFriendly(linkText) + "/p";
                                break;
                            case "demand":
                                rewriteUrl = "/" + TextHelper.ToUrlFriendly(clientName) + "/" + TextHelper.ToUrlFriendly(linkText) + "/dm";
                                break;
                            case "project":
                                rewriteUrl = "/" + TextHelper.ToUrlFriendly(clientName) + "/pr";
                                break;
                            default:
                                rewriteUrl = string.Format(rewriteUrl, "s");
                                break;
                        }

                        break;
                    case "listing":
                        rewriteUrl = string.Format(rewriteUrl, "i");
                        break;
                    case "directories":
                        rewriteUrl = "/" + TextHelper.ToUrlFriendly(clientName) + "/dc";
                        break;
                    case "details":
                        rewriteUrl = "/" + TextHelper.ToUrlFriendly(clientName) + "/" + TextHelper.ToUrlFriendly(linkText) + "-{0}" + controller.Substring(0, 1);
                        rewriteUrl = string.Format(rewriteUrl, "dt");
                        break;
                    case "more":
                        rewriteUrl = "/" + TextHelper.ToUrlFriendly(clientName) + "/" + TextHelper.ToUrlFriendly(linkText) + "-{0}" + controller.Substring(0, 1);
                        rewriteUrl = string.Format(rewriteUrl, "mo");
                        break;
                    default:
                        rewriteUrl = string.Format(rewriteUrl, action.Substring(0, 1));
                        break;
                }
                */

                switch (action.ToLower())
                {
                    case "details":
                    case "more":
                        foreach (var item in this.viewContext.RequestContext.RouteData.Values)
                        {
                            if (item.Value.ToString() != controller && item.Value.ToString() != action && item.Value.ToString() != clientName && item.Key != "id")
                            {
                                actionLink.Append("-").Append(item.Value.ToString());
                            }
                        }
                        actionLink.Append(".html");
                        break;
                    default:
                        foreach (var item in this.viewContext.RequestContext.RouteData.Values)
                        {
                            if (item.Value.ToString() != controller && item.Value.ToString() != action && item.Value.ToString() != clientName && item.Key != "id")
                            {
                                actionLink.Append("/").Append(item.Value);
                            }
                        }
                        break;
                }
                link = rewriteUrl + actionLink.ToString();
                var param = string.Empty;
                foreach (var item in pageLinkValueDictionary)
                {
                    if (item.Value != null && item.Value.ToString() != string.Empty)
                    {
                        param += item.Key + "=" + item.Value + "&";
                    }
                }
                //var rewrite = Utils.ParseInt(id) >= 0 ? TextHelper.ToUrlShort(link) : link;
                link = param != string.Empty ? (link + "?" + param.TrimEnd('&')) : link;
                return String.Format(linkFormat, link, linkText);
                //return String.Format(linkFormat, clientName != null && clientName != string.Empty ? ("/" + clientName + virtualPathData.VirtualPath) : virtualPathData.VirtualPath, linkText);
            }
            else
            {
                return null;
            }
        }
		private string GeneratePageLink(string linkText, int pageNumber)
		{
			var pageLinkValueDictionary = new RouteValueDictionary(this.linkWithoutPageValuesDictionary);
			pageLinkValueDictionary.Add("page", pageNumber);
			var virtualPathData = RouteTable.Routes.GetVirtualPathForArea(this.viewContext.RequestContext, pageLinkValueDictionary);

			if (virtualPathData != null)
			{
				string linkFormat = "<a href=\"{0}\">{1}</a>";
				return String.Format(linkFormat, virtualPathData.VirtualPath, linkText);
			}
			else
			{
				return null;
			}
		}
	}
}